package cn.lili.event.impl;

import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.event.AfterSaleStatusChangeEvent;
import cn.lili.event.GoodsCommentCompleteEvent;
import cn.lili.event.OrderStatusChangeEvent;
import cn.lili.event.UserRegisterEvent;
import cn.lili.modules.member.entity.dos.MemberEvaluation;
import cn.lili.modules.member.entity.dos.User;
import cn.lili.modules.order.aftersale.entity.dos.AfterSale;
import cn.lili.modules.order.order.client.OrderClient;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dto.OrderMessage;
import cn.lili.modules.order.order.entity.enums.OrderPromotionTypeEnum;
import cn.lili.modules.order.order.entity.enums.PayStatusEnum;
import cn.lili.modules.order.trade.entity.enums.AfterSaleStatusEnum;
import cn.lili.modules.payment.client.WalletPointClient;
import cn.lili.modules.payment.entity.dto.UserPointUpdateDTO;
import cn.lili.modules.payment.entity.enums.UserPointServiceEnum;
import cn.lili.modules.system.client.SettingClient;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.PointSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import com.google.gson.Gson;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * 用户积分
 *
 * @author Bulbasaur
 * @since 2020-07-03 11:20
 */
@Service
@RequiredArgsConstructor
public class UserPointExecute implements UserRegisterEvent, GoodsCommentCompleteEvent, OrderStatusChangeEvent, AfterSaleStatusChangeEvent {


    private final SettingClient settingClient;

    private final WalletPointClient pointClient;

    private final OrderClient orderClient;

    /**
     * 会员注册赠送积分
     *
     * @param member 会员
     */
    @Override
    public void userRegister(User member) {
        //获取积分设置
        PointSetting pointSetting = getPointSetting();
        //赠送用户积分
        pointClient.updateMemberPoint(
                UserPointUpdateDTO.builder()
                        .userId(member.getId())
                        .points(pointSetting.getRegister())
                        .userPointServiceEnum(UserPointServiceEnum.SIGN)
                        .description("会员注册，赠送积分" + pointSetting.getRegister() + "分").build()
        );
    }

    /**
     * 会员评价赠送积分
     *
     * @param memberEvaluation 会员评价
     */
    @Override
    public void goodsComment(MemberEvaluation memberEvaluation) {
        //获取积分设置
//        PointSetting pointSetting = getPointSetting();
        //赠送用户积分
//        pointClient.updateMemberPoint(
//                UserPointUpdateDTO.builder()
//                        .userId(memberEvaluation.getId())
//                        .points(pointSetting.getComment().longValue())
//                        .userPointServiceEnum(UserPointServiceEnum.PAYMENT_GIFT)
//                        .description("会员评价，赠送积分" + pointSetting.getComment() + "分").build()
//        );
    }

    /**
     * 非积分订单订单完成后赠送积分
     *
     * @param orderMessage 订单消息
     */
    @Override
    public void orderChange(OrderMessage orderMessage) {

        switch (orderMessage.getNewStatus()) {
            case CANCELLED -> {
                Order order = orderClient.getBySn(orderMessage.getOrderSn());
                Double point = order.getPriceDetailDTO().getPayPoint();
                if (point <= 0) {
                    return;
                }
                Integer redPack = order.getPriceDetailDTO().getPayRedPack();
                if (redPack <= 0) {
                    return;
                }
                //如果未付款，则不去要退回相关代码执行
                if (order.getPayStatus().equals(PayStatusEnum.UNPAID.name())) {
                    return;
                }
                String content = "订单取消，积分返还：" + point + "分";
                //赠送用户积分
                pointClient.updateMemberPoint(
                        UserPointUpdateDTO.builder()
                                .userId(order.getBuyerId())
                                .points(point)
                                .userPointServiceEnum(UserPointServiceEnum.ORDER_CANCEL)
                                .description(content).build());
            }
            case COMPLETED -> {
                Order order = orderClient.getBySn(orderMessage.getOrderSn());
                //如果是积分订单 则直接返回
                if (CharSequenceUtil.isNotEmpty(order.getOrderPromotionType())
                        && order.getOrderPromotionType().equals(OrderPromotionTypeEnum.POINTS.name())) {
                    return;
                }
                //获取积分设置
                PointSetting pointSetting = getPointSetting();
                if (pointSetting.getConsumer() == 0) {
                    return;
                }
                //计算赠送积分数量
                Double point = CurrencyUtil.mul(pointSetting.getConsumer(), order.getFlowPrice(), 0);
                //赠送用户积分
                pointClient.updateMemberPoint(
                        UserPointUpdateDTO.builder()
                                .userId(order.getBuyerId())
                                .points(point)
                                .userPointServiceEnum(UserPointServiceEnum.PAYMENT_GIFT)
                                .description("会员下单，赠送积分" + point.longValue() + "分").build()
                );
            }
            default -> {
            }
        }
    }


    /**
     * 提交售后后扣除积分
     *
     * @param afterSale 售后
     */
    @Override
    public void afterSaleStatusChange(AfterSale afterSale) {
        if (afterSale.getServiceStatus().equals(AfterSaleStatusEnum.COMPLETE.name())) {
            //获取积分设置
            PointSetting pointSetting = getPointSetting();
            //计算扣除积分数量
            Double point = CurrencyUtil.mul(pointSetting.getMoney(), afterSale.getActualRefundPrice(), 0);

            if(point == 0) {
                return;
            }

            //扣除用户积分
            pointClient.updateMemberPoint(
                    UserPointUpdateDTO.builder()
                            .userId(afterSale.getMemberId())
                            .points(point)
                            .userPointServiceEnum(UserPointServiceEnum.RETURN)
                            .description("会员退款，回退积分" + point + "分").build());

        }
    }

    /**
     * 获取积分设置
     *
     * @return 积分设置
     */
    private PointSetting getPointSetting() {
        Setting setting = settingClient.get(SettingEnum.POINT_SETTING.name());
        return new Gson().fromJson(setting.getSettingValue(), PointSetting.class);
    }
}
